package com.smarttable.ysd;

import java.util.ArrayList;
import java.util.List;

import com.smarttable.ysd.bean.AppInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.Toast;

/**
 * App管理者,用来获取设备上的所有app
 * 
 * @author Administrator
 * 
 */
public class AppManager {

  private static AppManager mInstance;
  public static int currentAppCategory = 0;
  public static final String APP_DIVIDE = "::";// 分隔符
  //游戏
  public static final String CATEGORY_GAME_FILE = "Category_Game_File";
  public static final String CATEGORY_GAME_FILE_KEY= "Category_Game_File_Cn";
  //视频
  public static final String CATEGORY_VIDEO_FILE = "Category_Video_File";
  public static final String CATEGORY_VIDEO_FILE_KEY= "Category_Video_File_Cn";
  
  //测试
  public static final String CATEGORY_TEST_FILE = "Category_Test_File";
  public static final String CATEGORY_TEST_FILE_KEY= "Category_Test_File_Cn";
  public static AppManager getInstance() {
    if (mInstance == null) {
      mInstance = new AppManager();
    }
    return mInstance;
  }

  /*
   * 获取设备中所有App信息
   */
  public ArrayList<AppInfo> getAppList(Context context) {

    ArrayList<AppInfo> appList = new ArrayList<AppInfo>();
    Intent intent = new Intent(Intent.ACTION_MAIN, null);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    List<ResolveInfo> mApps = context.getPackageManager().queryIntentActivities(intent, 0);
    ResolveInfo info = null;
    for (int i = 0; i < mApps.size(); i++) {
      info = mApps.get(i);
      String packagename = info.activityInfo.packageName;
      boolean isUserApp = checkAppType(context, packagename) == 1 ? true : false;
      if (isUserApp) {// 系统App不显示
        String appLabel = info.loadLabel(context.getPackageManager()).toString();
        String className = info.activityInfo.name;
        Drawable appIcon = info.activityInfo.loadIcon(context.getPackageManager());
        ComponentName cn = new ComponentName(packagename, className);
        // 汉字转换成拼音
        String byName = AppCollectorUtils.getPinYin(appLabel);
        AppInfo appInfo = new AppInfo(appLabel, appIcon, cn, isUserApp, byName);
        appList.add(appInfo);
      }
    }
    return appList;
  }
  
  /*
   * 将App信息添加到对应类别的配置文件中
   */
    public void addAppInfoToTheirXMLFile(int category ,AppInfo info,Context context){
      String[] strs = getSPNameAndKeyByCategory(category);
      String name = strs[0];
      String key = strs[1];
      SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
      StringBuilder  oldCns = new StringBuilder(sp.getString(key, "").trim());
      String text = oldCns.toString().trim();
      String divide="";
      String addCn = info.getCn().getPackageName()+"/"+info.getCn().getClassName();
      if (oldCns==null || oldCns.length()==0) {
        divide = "";
      }else {
        divide = APP_DIVIDE;
        if (text.contains(addCn)) {//重复添加
          Toast.makeText(context, context.getResources().getString(R.string.tip_has_add_same_icon), Toast.LENGTH_LONG).show();
          return;
        }
      }
      addCn = divide+addCn;
      oldCns.append(addCn);
      sp.edit().putString(key, oldCns.toString().trim()).commit();
    }
    
    /*
     * 将App信息从对应类别的配置文件中删除
     */
    public void delAppInfoFromTheirXMLFile(int category,AppInfo info,Context context){
      String[] strs = getSPNameAndKeyByCategory(category);
      String name = strs[0];
      String key = strs[1];
      SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
      StringBuilder  oldCns = new StringBuilder(sp.getString(key, "").trim());
      String text = oldCns.toString().trim();
      String delCn = info.getCn().getPackageName()+"/"+info.getCn().getClassName();
      if (text.contains(delCn)) {
        String[] cns = text.split(APP_DIVIDE);
        if (cns.length==1) {//originalCns中cn的数量只有一个并且为delCn
          oldCns.delete(0, delCn.length());
        }else {//originalCns中cn的数量大于一个
          if (text.indexOf(delCn)==0) {//delCn为text中的第一个cn
            delCn = delCn + APP_DIVIDE;
          }else {
            delCn = APP_DIVIDE+delCn;
          }
          int start = oldCns.indexOf(delCn);
          oldCns.delete(start, start+delCn.length());
        }        
        sp.edit().putString(key, oldCns.toString().trim()).commit();
      }
    }
    
    /*
     * 从配置文件中取出对应类别的App信息
     */
    public ArrayList<AppInfo> getAppInfoByCategoryFromXMLFile(int category,Context context){
      String[] strs = getSPNameAndKeyByCategory(category);
      String name = strs[0];
      String key = strs[1];
      SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
      String cnString = sp.getString(key, "");
      Log.d("berrytao","解析category="+category+"配置文件【"+cnString+"】");
      if ("".equals(cnString.trim()) ) {
        return null;
      }
      String[] cns = cnString.split(AppManager.APP_DIVIDE);
      if (cns!=null && cns.length>0) {
        return getAppInfoFromString(cns, context);
      }
      return null;
    }
    
    /*
     * 根据category取相应的sharedpreferences需要的name与key
     */
    private String[] getSPNameAndKeyByCategory(int category){
      String[] strs = {"",""};
      switch (category) {
        case 1:
          strs[0] = AppManager.CATEGORY_GAME_FILE;
          strs[1] = AppManager.CATEGORY_GAME_FILE_KEY;
          break;
        case 2:
          strs[0] = AppManager.CATEGORY_VIDEO_FILE;
          strs[1] = AppManager.CATEGORY_VIDEO_FILE_KEY;
          break;
        case 3:
          strs[0] = AppManager.CATEGORY_TEST_FILE;
          strs[1] = AppManager.CATEGORY_TEST_FILE_KEY;
          break;
        default:
          break;
      }
      return strs;
    }
    
    private ArrayList<AppInfo> getAppInfoFromString(String[] cnsString,Context context){
      ArrayList<AppInfo> apps = new ArrayList<AppInfo>();
      for (int i = 0; i < cnsString.length; i++) {
          Log.d("berrytao", "i="+i+",str="+cnsString[i]);
          AppInfo app = parseAppInfoByPkg(context, cnsString[i]);
          if (app!=null) {
            apps.add(app);
          }
        
      }
      return apps;
    
    }
    
    private AppInfo parseAppInfoByPkg(Context context,String cn){
      PackageManager pManager = context.getPackageManager();
      String[] cnStr = cn.split("/");
      try {
        ActivityInfo info = pManager.getActivityInfo(new ComponentName(cnStr[0], cnStr[1]), 0);
        Drawable icon = info.loadIcon(pManager);
        String title = info.loadLabel(pManager).toString();
//        boolean isUserApp = checkAppType(context,cnStr[0])==1?true:false;
        return new AppInfo(title, icon, new ComponentName(cnStr[0], cnStr[1]), true, "");
      } catch (NameNotFoundException e) {
        Log.d("berrytao", "解析失败，cn="+cn);
        return null;
      }
    }
    
  // 未知软件类型
  public static final int UNKNOW_APP = 0;
  // 用户软件类型
  public static final int USER_APP = 1;
  // 系统软件
  public static final int SYSTEM_APP = 2;
  // 系统升级软件
  public static final int SYSTEM_UPDATE_APP = 4;
  // 系统+升级软件
  public static final int SYSTEM_REF_APP = SYSTEM_APP | SYSTEM_UPDATE_APP;

  /**
   * 检查app是否是系统rom集成的
   * 
   * @param pname
   * @return
   */
  private int checkAppType(Context context, String pname) {
    try {
      PackageInfo pInfo = context.getPackageManager().getPackageInfo(pname, 0);
      // 是系统软件或者是系统软件更新
      if (isSystemApp(pInfo) || isSystemUpdateApp(pInfo)) {
        return SYSTEM_REF_APP;
      } else {
        return USER_APP;
      }

    } catch (NameNotFoundException e) {
      return UNKNOW_APP;
    }
  }

  /**
   * 是否是系统软件或者是系统软件的更新软件
   * 
   * @return
   */
  public boolean isSystemApp(PackageInfo pInfo) {
    return ((pInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
  }

  public boolean isSystemUpdateApp(PackageInfo pInfo) {
    return ((pInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
  }

  public boolean isUserApp(PackageInfo pInfo) {
    return (!isSystemApp(pInfo) && !isSystemUpdateApp(pInfo));
  }

}
